/*
 * User Controller
 * @Author: chiangbt@geoportal.cn 
 * @Date: 2019-05-05 14:31:52 
 * @Last Modified by: chiangbt@geoportal.cn
 * @Last Modified time: 2019-05-09 11:06:12
 */
const mongoose = require("mongoose");
const async = require('async');
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const User = require("../models/user");

/**
 * 注册用户
 */
exports.user_singup = (req, res, next) => {
    // 查看email或username是否存在
    User.findOne({
            $or: [{
                username: req.body.username
            }, {
                email: req.body.email
            }]
        })
        .then(user => {
            // email或username已经注册
            if (user) {
                return res.status(409).json({
                    success: false,
                    message: "用户已经存在"
                });
            } else {
                // 将密码hash化
                bcrypt.hash(req.body.password, 10, (err, hash) => {
                    if (err) {
                        return res.status(500).json({
                            success: false,
                            error: err.message
                        });
                    } else {
                        // 新建一个用户
                        const user = new User({
                            _id: new mongoose.Types.ObjectId(),
                            username: req.body.username,
                            email: req.body.email,
                            password: hash
                        });
                        user.save()
                            .then(result => {
                                return res.status(201).json({
                                    success: true,
                                    message: "用户注册成功"
                                });
                            })
                            .catch(err => {
                                return res.status(500).json({
                                    success: false,
                                    message: "用户Email格式不正确"
                                });
                            });
                    }
                });
            }
        });
};

/**
 * 用户登录
 */
exports.user_login = (req, res, next) => {
    User.findOne({
            $or: [{
                username: req.body.loginname
            }, {
                email: req.body.loginname
            }]
        })
        .then(user => {
            if (!user) {
                return res.status(404).json({
                    success: false,
                    message: "用户尚未注册"
                });
            } else {
                bcrypt.compare(req.body.password, user.password, (err, result) => {
                    if (err) {
                        return res.status(401).json({
                            success: false,
                            message: "用户密码不正确"
                        });
                    }
                    if (result) {
                        const token = jwt.sign({
                                id: user._id,
                                username: user.username,
                                email: user.email,
                                active: user.isActive,
                                role: user.role
                            },
                            process.env.SecretOrPublicKey, {
                                expiresIn: process.env.TOKEN_EXPRIED
                            }
                        );
                        return res.status(200).json({
                            success: true,
                            message: "Auth验证成功",
                            userId: user._id,
                            token: token,
                            ttl: jwt.decode(token).exp
                        });
                    } else {
                        return res.status(401).json({
                            success: false,
                            message: "用户密码不正确"
                        });
                    }
                });
            }
        })
        .catch(err => {
            return res.status(500).json({
                success: false,
                error: err
            });
        });
};

/**
 * 用户重置密码,由于重置密码的流程包括：查找用户、检核密码、生成hash、更新密码
 * 这四个过程均为异步，因此需要使用async.waterfall进行组织
 */
exports.user_resetpassword = (req, res, next) => {
    async.waterfall([
        // 寻找用户
        function (done) {
            User.findOne({
                email: req.body.email
            }).then(user => {
                if (user) {
                    done(null, user);
                } else {
                    return res.status(404).json({
                        success: false,
                        message: "用户不存在"
                    });
                }
            });
        },
        // 比对密码
        function (user, done) {
            bcrypt.compare(req.body.password, user.password, (err, result) => {
                if (err) {
                    return res.status(401).json({
                        success: false,
                        message: "Auth验证失败"
                    });
                }
                if (result) {
                    done(err, user);
                } else {
                    return res.status(401).json({
                        success: false,
                        message: "用户原始密码不正确"
                    });
                }
            });
        },
        // 生成新密码的hash
        function (user, done) {
            bcrypt.hash(req.body.password2, 10, (err, hash) => {
                if (err) {
                    return res.status(401).json({
                        success: false,
                        message: "Auth验证失败"
                    });
                }
                if (hash) {
                    done(err, user, hash);
                }
            });
        },
        // 更新密码
        function (user, hash, done) {
            user.password = hash;
            user.save(function (err) {
                if (err) {
                    return res.status(500).json({
                        success: false,
                        message: "密码重置失败"
                    });
                } else {
                    return res.status(200).json({
                        success: true,
                        message: "密码重置成功"
                    });
                }
                done(err);
            });
        },
    ], function (err) {
        if (err) {
            return res.status(500).json({
                success: false,
                message: err.message
            });
        }
    });
};

/**
 * 使用token获取用户信息
 */
exports.user_profile = (req, res, next) => {
    if (!req.headers.authorization) {
        res.status(401).json({
            success: false,
            message: "请求的Headers中未携带Token"
        });
    } else {
        const token = req.headers.authorization.split(" ")[1];
        const decoded = jwt.verify(token, process.env.SecretOrPublicKey);
        User.findOne({
            _id: decoded.id
        }).then(user => {
            if (user) {
                return res.status(200).json({
                    success: true,
                    message: "用户存在",
                    user: {
                        id: user._id,
                        username: user.username,
                        email: user.email,
                        isActive: user.isActive,
                        role: user.role
                    }
                });
            } else {
                return res.status(404).json({
                    success: false,
                    message: "用户不存在"
                });
            }
        });
    }
};

/**
 * 获取指定id的用户
 */
exports.user_get_by_id = (req, res, next) => {
    User.findOne({
        _id: req.params.id
    }).then(user => {
        if (user) {
            return res.status(200).json({
                success: true,
                message: '指定User对象获取成功',
                user: {
                    id: user._id,
                    email: user.email,
                    username: user.username,
                    role: user.role,
                    isActive: user.isActive
                }
            });
        } else {
            return res.status(400).json({
                success: false,
                error: '指定要的User对象不存在'
            });
        }
    }).catch(err => {
        return res.status(400).json({
            success: false,
            error: err.message
        });
    });
}

/**
 * 删除用户
 */
exports.user_delete = (req, res, next) => {
    User.findOneAndRemove({
            _id: req.params.id
        })
        .then(result => {
            if (result) {
                return res.status(200).json({
                    success: true,
                    message: '指定User对象删除成功'
                });
            } else {
                return res.status(400).json({
                    success: false,
                    error: '指定要删除的User对象不存在'
                });
            }
        })
        .catch(err => {
            return res.status(400).json({
                success: false,
                error: err.message
            });
        });
};

/**
 * 查看用户信息
 */
exports.user_get_all = (req, res, next) => {
    const limit = parseInt(req.query.limit) || 15
    const offset = parseInt(req.query.offset) || 0

    User.count({}, function (err, counts) {
        User.find().sort({
                '_id': -1
            })
            .skip(offset).limit(limit)
            .then(users => {
                return res.status(200).send({
                    success: true,
                    count: counts,
                    results: users.map(user => {
                        return {
                            id: user._id,
                            username: user.username,
                            email: user.email,
                            role: user.role,
                            isActive: user.isActive,
                            createdAt: user.createdAt
                        }
                    })
                })
            })
            .catch(err => {
                return res.status(500).json({
                    success: false,
                    error: err
                });
            });
    })
};

/**
 * 更新用户角色
 */
exports.user_update = (req, res, next) => {
    const id = req.params.id;
    const user = req.body;
    const {
        ...updateData
    } = user

    User.findByIdAndUpdate({
            _id: id
        }, updateData, {
            new: true
        })
        .then(user => {
            if (user) {
                return res.status(200).json({
                    success: true,
                    result: user
                });
            } else {
                return res.status(400).json({
                    success: false,
                    error: '更新的user并不存在'
                });
            }
        })
        .catch(err => {
            return res.status(500).json({
                success: false,
                error: err.message
            });
        });
};